home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
misc
/
emu
/
QDOS2.lha
/
QLsource
/
ROMsrc
/
KBD
/
KBD_asm
Wrap
Text File
|
1995-08-30
|
34KB
|
1,728 lines
SECTION KBD
INCLUDE '/INC/QDOS_inc'
INCLUDE '/INC/AMIGA_inc'
INCLUDE '/INC/AMIGQDOS_inc'
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; KBD1_asm - Keyboard routines
; - last modified 30/08/95
; These are all the necessary keyboard related sources, required
; to implement QDOS keyboard routines on the Amiga computer.
; Amiga-QDOS sources by Rainer Kowallik
; ...latest changes by Mark J Swift
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ROM header
BASE:
dc.l $4AFB0001 ; ROM recognition code
dc.w PROC_DEF-BASE ; add BASIC procs here
dc.w ROM_START-BASE
dc.b 0,36,'Amiga-QDOS KEYBOARD routines v1.25 ',$A
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; start of ROM code
ROM_START:
movem.l d0-d3/a0-a3,-(a7)
; --------------------------------------------------------------
; allocate memory for keyboard variables
move.l #KV_LEN,d1
moveq #MT.ALCHP,d0
moveq #0,d2
trap #1
; --------------------------------------------------------------
; address of keyboard variables
move.l a0,AV.KEYV
move.l a0,a3
; --------------------------------------------------------------
; enter supervisor mode and disable interrupts
trap #0
ori.w #$0700,sr ; disable interrupts
; --------------------------------------------------------------
; link a custom routine into level 7 interrupt server
lea AV.LVL7link,a1
lea KV.LVL7link(a3),a2
move.l (a1),(a2)
move.l a2,(a1)
lea MY_LVL7(pc),a1
move.l a1,$04(a2)
; --------------------------------------------------------------
; link a custom routine into Trap #1 exception
lea AV.TRP1link,a1
lea KV.TRP1link(a3),a2
move.l (a1),(a2)
move.l a2,(a1)
lea MY_TRP1(pc),a1
move.l a1,$04(a2)
; --------------------------------------------------------------
; initialise relevant hardware
bsr INIT_HW
; -------------------------------------------------------------
; link in external interrupt to act on keyboard press
lea XINT_SERver(pc),a1 ; address of routine
lea KV.XINTLink(a3),a0
move.l a1,4(a0)
moveq #MT.LXINT,d0
trap #1
; --------------------------------------------------------------
; link in polled task routine to handle keyboard
lea POLL_SERver(pc),a1 ; address of routine
lea KV.POLLLink(a3),a0
move.l a1,4(a0) ; address of polled task
moveq #MT.LPOLL,d0
trap #1
; --------------------------------------------------------------
; enable interrupts and re-enter user mode
andi.w #$D8FF,sr
; --------------------------------------------------------------
ROM_EXIT:
movem.l (a7)+,d0-d3/a0-a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; initialise keyboard for use.
INIT_HW:
movem.l d0-d2/a0/a3,-(a7)
; --------------------------------------------------------------
; set ASCII table and clear actual key.
move.l AV.KEYV,a3 ; address of keyboard vars
lea QLASCII(pc),a0
move.l a0,KV.QLASCtbl(a3)
clr.w KV.ACTKEy(a3) ; reset actual key
move.w #0,KV.PTRMINX(a3)
move.w #0,KV.PTRMINY(a3)
move.w #255,KV.PTRMAXX(a3)
move.w #255,KV.PTRMAXY(a3)
move.w #0,KV.PTROLDX(a3)
move.w #0,KV.PTROLDY(a3)
move.w #0,KV.PTRX(a3)
move.w #0,KV.PTRY(a3)
move.w #4,KV.PTRINCX(a3)
move.w #8,KV.PTRINCY(a3)
; --------------------------------------------------------------
; initialise hardware
move.b CIAA_ICR,d0 ; read & clear CIA-A ICR
or.b AV.CIAA_ICR,d0
bclr #3,d0 ; clear SP bit
move.b d0,AV.CIAA_ICR ; store for another program
move.w #%0000000000001000,INTREQ ; clear and enable
move.w #%1000000000001000,INTENA ; CIA-A interrupts
move.b #%10001000,CIAA_ICR ; enable SP interrupt
ori.b #%00001000,AV.CIAA_MSK ; take note
movem.l (a7)+,d0-d2/a0/a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; external interrupt server
XINT_SERver:
movem.l d7/a0,-(a7)
move.w INTENAR,d7 ; read interrupt enable reg
btst #3,d7 ; branch if ints not on
beq XINT_OTHer
move.w INTREQR,d7 ; read interrupt request reg
btst #3,d7 ; branch if from CIA-A or
bne CIAA_SERV ; expansion ports
; --------------------------------------------------------------
; otherwise let another external interrupt server handle it
XINT_OTHer:
movem.l (a7)+,d7/a0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Interrupt from CIA-A or expansion port
CIAA_SERV:
move.b CIAA_ICR,d7 ; read CIA-A ICR
or.b AV.CIAA_ICR,d7
move.b d7,AV.CIAA_ICR ; store for another program
bclr #3,d7 ; keyboard? (SP bit=1)
beq XINT_OTHer ; no
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; external interrupt server for acting on an a key press.
; The Result is stored in KV.ACTKEy (word) (MSB=ASCII,LSB=ALT)
RDKEYB:
move.b d7,AV.CIAA_ICR
and.b AV.CIAA_MSK,d7 ; don't clear intreq if
bne.s RDKEYB0 ; other CIAA ints occured
move.w #%0000000000001000,INTREQ ; clear interrupts
; --------------------------------------------------------------
RDKEYB0:
movem.l d0/a0/a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
BSR KEYread
tst.b KV.ACTKEy+1(a3)
beq RDKEYBX
; --------------------------------------------------------------
; Check for CTRL-ALT-2 and simulate a level 2 interrupt
RDKEYB1:
move.w KV.ACTKEy(a3),d0
cmp.w #$92FF,d0 ; CTRL 2/ALT ?
bne.s RDKEYB2
clr.w KV.ACTKEy(a3) ; reset keypress
ori.w #$0700,sr ; mask out all interrupts
move.w #$8000,d7
WAITABIT2:
move.w #RED,COLOR00 ; signal forced interrupt
move.w #0,COLOR00 ; via DMA-test pattern
dbra d7,WAITABIT2
adda.l #$24,a7 ;*/note JS specific
movem.l (a7)+,d0-d6/a0-a4 ; drop out of external
movem.l (a7)+,d7/a5/a6 ; interrupt call
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.MAINlink,a3
move.l 4(a3),4(a7) ; address of 1st routine
movem.l (a7)+,a3
rts ; jump to routine
; --------------------------------------------------------------
; Check for CTRL-ALT-5 and simulate a level 5 interrupt
RDKEYB2:
move.w KV.ACTKEy(a3),d0
cmp.w #$95FF,d0 ; CTRL 5/ALT ?
bne.s RDKEYB3
clr.w KV.ACTKEy(a3) ; reset keypress
ori.w #$0700,sr ; mask out all interrupts
move.w #$8000,d7
WAITABIT5:
move.w #CYAN,COLOR00 ; signal forced interrupt
move.w #0,COLOR00 ; via DMA-test pattern
dbra d7,WAITABIT5
adda.l #$24,a7 ;*/note JS specific
movem.l (a7)+,d0-d6/a0-a4 ; drop out of external
movem.l (a7)+,d7/a5/a6 ; interrupt call
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.LVL5link,a3
move.l 4(a3),4(a7) ; address of 1st routine
movem.l (a7)+,a3
rts ; jump to routine
; --------------------------------------------------------------
; Check for CTRL-ALT-7 and simulate a level 7 interrupt
RDKEYB3:
move.w KV.ACTKEy(a3),d0
cmp.w #$97FF,d0 ; CTRL 7/ALT ?
bne.s RDKEYB4
clr.w KV.ACTKEy(a3) ; reset keypress
ori.w #$0700,sr ; mask out all interrupts
move.b #$7F,CIAA_ICR ; no ints from CIA-A
move.b #$7F,CIAB_ICR ; no ints from CIA-B
move.w #$7FFF,INTREQ ; clear interrupt requests
move.w #$7FFF,INTENA ; disable interrupts
ALT7_BZY:
btst #6,DMACONR ; wait for blitter
bne.s ALT7_BZY
move.w #$07FF,DMACON ; no DMA, no blitter prio'ty
move.w #$8000,d7
WAITABIT7:
move.w #WHITE,COLOR00 ; signal forced interrupt
move.w #0,COLOR00 ; via DMA-test pattern
dbra d7,WAITABIT7
adda.l #$24,a7 ;*/note JS specific
movem.l (a7)+,d0-d6/a0-a4 ; drop out of external
movem.l (a7)+,d7/a5/a6 ; interrupt call
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.LVL7link,a3
move.l 4(a3),4(a7) ; address of 1st routine
movem.l (a7)+,a3
rts ; jump to routine
; --------------------------------------------------------------
; Check for CTRL-SHIFT-ALT-TAB and perform a reset
RDKEYB4:
move.l KV.SHIFTflg(a3),d0
cmp.l #(%00000111<<24)|$09FF,d0 ; ALT/CTRL/SHIFT/TAB/ALT
bne.s RDKEYB5
clr.w KV.ACTKEy(a3) ; reset keypress
ori.w #$0700,sr ; mask out all interrupts
move.b #$7F,CIAA_ICR ; no ints from CIA-A
move.b #$7F,CIAB_ICR ; no ints from CIA-B
move.w #$7FFF,INTREQ ; clear interrupt requests
move.w #$7FFF,INTENA ; disable interrupts
ALTT_BZY:
btst #6,DMACONR ; wait for blitter
bne.s ALTT_BZY
move.w #$07FF,DMACON ; no DMA, no blitter prio'ty
movem.l (a7)+,d0/a0/a3
movem.l (a7)+,d7
move.l $0,a7 ; reset supervisor stack
move.l $4,-(a7) ; call first reset routine
rts
; --------------------------------------------------------------
RDKEYB5:
RDKEYBX:
movem.l (a7)+,d0/a0/a3
; -------------------------------------------------------------
XINT_EXIt:
bra XINT_OTHer
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Subroutine to read keyboard value from hardware
KEYread:
movem.l d0-d3/a0/a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
lea CIAA,a0 ; now implement Keyboard
moveq #0,d0 ; handshake according to
move.b d0,CRA(a0) ; ROM listing ($FE5478)
move.b d0,CRA(a0)
move.b #$40,CRA(a0) ; switch off keyboard
move.b CIAA_SP,d0 ; read raw key code
move.l #$40,d2
WTKEYB0:
nop
dbra d2,WTKEYB0
move.b #$0,CIAA_CRA ; switch on keyboard again
MOVE.L #255,D1
SUB.B D0,D1 ; calculate key stroke
LSR.B #1,D1
AND.W #1,D0 ; only press/release bit
; --------------------------------------------------------------
; first convert to QL raw key code
LEA QLRAWKEY(PC),A0
MOVEQ #0,D2
MOVE.B 0(A0,D1.W),D2 ; get row and bit number
bge.s KEYrd2b ; branch on valid key
clr.w KV.ACTKEy(a3) ; otherwise, reset actual key
lea KV.STORAwkey(a3),a0
clr.l (a0)+
clr.l (a0)+ ; invalidate KEYROW bits
clr.l (a0)+
clr.l (a0)+
clr.w $90(a6) ; disable key repeat
bra KEYrdX1
KEYrd2b:
MOVE.L D2,D3
LSR.L #4,D3 ; extract row number -> D3
AND.W #$7,D3
AND.B #$07,D2 ; extract bit number -> D2
lea KV.STORAwkey(a3),a0
BSET D2,0(A0,D3.W)
CMP.B #1,D0 ; press or release ?
BEQ.S KEYCVASC
BCLR D2,0(A0,D3.W)
; --------------------------------------------------------------
; now convert to ASCII
KEYCVASC:
MOVE.W #$FFFE,D2 ; mask for AND
CMP.B #$60,D1 ; shift/alt/amiga ?
BLT.S KEYrd2 ; ...nope
CMP.B #$62,D1 ; Caps lock ?
BNE.S KEYrd2a ...nope
CMP.B #1,D0 ; Caps on or off ?
SEQ D0
lea SV_CAPS(a6),A0 ; address $28088
MOVE.B D0,(A0) ; set CAPS flag
BRA KEYrdX
KEYrd2a:
AND.B #$7E,D1 ; Don't distinguish
; right/left
CMP.B #$60,D1 ; Shift ?
BEQ.S KEYrd1
LSL.W #1,D0 ; Bit 0 for Shift, 1 for
; ctrl
ROL.W #1,D2
CMP.B #$62,D1 ; CTRL ?
BEQ.S KEYrd1
LSL.W #1,D0 ; Bit 2 for Alt, 3 for Amiga
ROL.W #1,D2
CMP.B #$64,D1 ; ALT ?
BEQ.S KEYrd1
LSL.W #1,D0
ROL.W #1,D2
CMP.B #$66,D1 ; AMIGA ?
bne KEYrdX ; should never happen!
KEYrd1:
lea KV.SHIFTflg(a3),a0 ; get address of flag
AND.B D2,(A0) ; clear old status bit
OR.B D0,(A0) ; and set new status
andi.w #$0F00,(a0) ; only keep modifiers
clr.w KV.ACTKEy(a3) ; reset actual key
BRA KEYrdX
; --------------------------------------------------------------
; convert keycode (D1) and write result to ACTkey
KEYrd2:
CMP.B #1,D0 ; press or just release ?
BEQ.S KEYrd3
clr.w KV.ACTKEy(a3) ; reset actual key
bra KEYrdX
KEYrd3:
lea KV.SHIFTflg(a3),a0
MOVE.B (A0),D2 ; get current status of
; Shift
MOVE.B D2,D0 ; store for ALT check
AND.B #$3,D2 ; don't bother with Alt or
; Amiga
move.l KV.QLASCtbl(a3),a0 ; first try no shifts
CMP.B #0,D2
BEQ.S KEYrd4
lea $60(a0),a0 ; next try Shift only
CMP.B #1,D2
BEQ.S KEYrd4
lea $60(a0),a0 ; now try ctrl only
CMP.B #2,D2
BEQ.S KEYrd4
lea $60(a0),a0 ; must be <Ctrl>+<Shift>
KEYrd4:
andi.b #%01111111,d0 ; assume 'special'
cmp.b #$40,d1
bge.s KEYrd5 ; ...skip if so
ori.b #%10000000,d0 ; indicate a-z, 0-9
KEYrd5:
move.b d0,KV.SHIFTflg(a3)
MOVE.B 0(A0,D1.W),D1 ; get ASCII value
lea SV_CAPS(a6),a0 ; address $28088
TST.B (A0) ; check for CAPS lock
BEQ.S KEYrd6
CMP.B #'a',D1 ; check for lower case
; letter
BLT.S KEYrd6
CMP.B #'z',D1
BGT.S KEYrd6
SUB.B #32,D1 ; change to upper case
; letter
KEYrd6:
lea KV.ACTKEy(a3),a0
MOVE.B D1,(A0) ; Store new key
BTST #2,D0 ; ALT flag set ?
SNE D0
MOVE.B D0,1(A0) ; store ALT flag
MOVE.W (A0),D0 ; check for ALT and cursor
; key
AND.W #$E0FF,D0 ; don't bother with
; up,right,left,down
CMP.W #$C0FF,D0 ; check for cursor key
BNE.S KEYrd7
ADD.B #1,(A0) ; now make correct key code
CLR.B 1(A0) ; and clear ALT flag
KEYrd7:
move.w KV.ACTKEy(a3),d0
cmpi.b #$FF,d0 ; if part of ALT combination
beq.s KEYrdX ; exit now & let polled int
; put key into Q
bsr POLL_K ; otherwise put into Q
KEYrdX:
MOVE.W $8C(A6),$90(A6) ; delay -> count
KEYrdX1:
movem.l (a7)+,d0-d3/a0/a3
RTS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Polled interrupt routine to read the keyboard
POLL_SERver:
move.l AV.KEYV,a3 ; address of keyboard vars
move.w JOY0DAT,d0 ; get counter
move.w KV.STOMOuse(a3),d5
move.w #$8080,JOYTEST ; preset for next time
move.w JOY0DAT,KV.STOMOuse(a3)
cmp.w d5,d0
beq.s POLL_K
sub.b d5,d0
move.b d0,d1
ext.w d1
beq.s POLL_1
add.w KV.PTRX(a3),d1
move.w KV.PTRERRX(a3),d3
bsr PTR_CLPX
move.w d1,KV.PTRX(a3)
move.w d3,KV.PTRERRX(a3)
POLL_1:
ror.w #8,d0
ror.w #8,d5
sub.b d5,d0
move.b d0,d2
ext.w d2
beq.s POLL_2
add.w KV.PTRY(a3),d2
move.w KV.PTRERRY(a3),d4
bsr PTR_CLPY
move.w d2,KV.PTRY(a3)
move.w d4,KV.PTRERRY(a3)
POLL_2:
move.w KV.PTRX(a3),d1
move.w KV.PTRY(a3),d2
bsr PTR_POS
POLL_K:
MOVEA.L $4C(A6),A2 ; SV.KEYQ Pointer to a
; keyboard queue
MOVE.L A2,D0
beq.s POLL_EXIt ; no con_ open
tst.b (a2)
blt.s POLL_EXIt ; eof
POLL_3:
move.l KV.SHIFTflg(a3),d1 ; read Shift flags and
; ACTkey
ROR.W #8,D1 ; rotate ascii in position
cmp.b #0,d1 ; any key pressed ?
bne.s L02EEC ; yup!
NOKEY:
CLR.W $8A(A6) ; reset Autorepeat buffer
POLL_EXIt:
rts
; --------------------------------------------------------------
L02EEC:
CMP.L #(%00000010<<24)|$0020,D1 ; <CTL><SPC> ?
BEQ DO_BREAK
CMPI.W #$00F9,D1 ; = <CTL><F5> freeze
BEQ FREEZE
SF $33(A6) ; screen status
CMP.W $92(A6),D1 ; SV.CQCH Keyboard change
BEQ CTRL_C ; queue character code
CMP.W $8A(A6),D1 ; New Key ?
BEQ.S AREPOLD
MOVE.W D1,$8A(A6) ; store Key
MOVE.W $8C(A6),$90(A6) ; delay -> count
BRA.S AREPDO
; --------------------------------------------------------------
AREPOLD:
cmp.w #1,SV_POLLM(a6) ; no key repeat if part of
bgt POLL_EXIt ; a 'poll miss' time-slice
MOVE.W $90(A6),D2 ; get actual count
tst.w d2
beq.s POLL_EXIt ; exit if key-repeat disabled
SUBQ.W #1,D2 ; decrement count
MOVE.W D2,$90(A6) ; and store new value
TST.W D2 ; 0 reached ?
bne POLL_EXIt ; do nothing if not
MOVE.W $8E(A6),$90(A6) ; SV.ARFRQ Autorepeat
; 1/frequency
move.l d1,d3 ; save key-stroke
move.w IO.QTEST,a3
jsr (a3)
beq POLL_EXIt ; exit if queue not empty
move.l d3,d1 ; restore key-stroke
; --------------------------------------------------------------
AREPDO:
cmpi.w #$FF0A,d1 ; <ALT>-<RTN>
beq.s DO_HISTORY
cmpi.l #(%00000010<<24)|$0009,d1 ; <CTL>-<TAB>
beq.s DO_FLIP
ror.w #8,d1
CMPI.B #$FF,D1 ; <ALT> key ?
BNE.S L02F36
SWAP D1
move.w IO.QTEST,a3
jsr (a3)
CMPI.W #2,D2
BLT POLL_EXIt
SWAP D1
move.w IO.QIN,a3 ; put a byte (D1) into a
jsr (a3) ; queue (A2)
L02F36:
LSR.W #8,D1
move.w IO.QIN,a3 ; put a byte (D1) into a
jsr (a3) ; queue (A2)
bra POLL_EXIt
; --------------------------------------------------------------
DO_HISTORY:
move.l Q_NEXTIN(a2),a3
cmp.l Q_NXTOUT(a2),a3
bne POLL_EXIt
lea $10(a2),a4
DO_HLUP1:
cmp.l a4,a3
bne.s DO_HIS1
move.l Q_END(a2),a3
DO_HIS1:
cmp.b #$0A,-(a3)
beq.s DO_HIS2
cmp.l Q_NXTOUT(a2),a3
bne.s DO_HLUP1
bra POLL_EXIt
DO_HIS2:
move.l a3,Q_NEXTIN(a2)
move.l a3,Q_NXTOUT(a2)
DO_HLUP2:
cmp.l a4,a3
bne.s DO_HIS3
move.l Q_END(a2),a3
DO_HIS3:
cmp.b #$0A,-(a3)
bne.s DO_HLUP2
DO_HIS4:
addq.l #1,a3
cmpa.l Q_END(a2),a3
blt.s DO_HIS5
lea $10(a2),a3
DO_HIS5:
move.l a3,Q_NXTOUT(a2)
bra POLL_EXIt
; --------------------------------------------------------------
DO_FLIP:
bsr FLIPIT
bra POLL_EXIt
FLIPIT:
moveq #0,d0
move.b SV_MCSTA(a6),d0
swap d1
lsl.w #4,d0
move.b d0,d1
andi.b #%10100000,d1
lsr.b #2,d1
andi.b #%01010000,d0
or.b d1,d0
lsl.b #1,d0
lsr.w #4,d0
swap d1
eori.b #1<<MC..SCRN,d0 ; flip between screen 1/2
move.b d0,SV_MCSTA(a6)
andi.b #%10001010,d0
move.b d0,MC_STAT ; switch screen if necessary
rts
; --------------------------------------------------------------
DO_BREAK:
CLR.W KV.ACTKEy(A3) ; reset BREAK request
SF $33(A6) ; screen status
MOVEA.L $68(A6),A3 ; SV.JBBAS Pointer to base of
; job table
MOVEA.L (A3),A3
SF $F7(A3)
MOVE.W $14(A3),D0 ; job status (BASIC)
BEQ.S L02EEA ; not suspended
MOVE.B $13(A3),D0 ; priority of BASIC
BNE.S BRECON1
MOVE.B #$20,$13(A3) ; set priority to 32 if it
; was set to 0
BRECON1:
CLR.W $14(A3) ; release job
MOVE.L $0C(A3),D0 ; pointer to byte which will
; be cleared when job relea
BEQ.S L02EEA
MOVEA.L D0,A3 ; clear this byte
SF (A3)
L02EEA:
bra POLL_EXIt
; --------------------------------------------------------------
FREEZE:
CLR.W KV.ACTKEy(A3) ; reset FREEZE request
NOT.B $33(A6) ; Screen status
bra POLL_EXIt
; --------------------------------------------------------------
CTRL_C:
CLR.W KV.ACTKEy(A3) ; reset CTRL_C request
SWITCHQ:
bsr FNDCHN ; find channel base/ID
TST.B SD_CURF(A1) ; queue waiting ?
BGE.S L02F54 ; cursor active
BSR SD_CURE ; reactivate cursor
L02F54:
MOVEA.L (A2),A2 ; next queue
bsr FNDCHN ; find channel base/ID
TST.B SD_CURF(A1) ; next queue active ?
BNE.S CTRLC0 ; yup, continue
CMPA.L SV_KEYQ(A6),A2 ; Current key Q
BNE.S L02F54 ; next Q <> this Q
CTRLC0:
move.b SV_MCSTA(a6),d0
cmp.l #$20000,SD_SCRB(a1)
bne.s CTRLC1
andi.b #$FF-(1<<MC..SCRN),d0
bra.s CTRLC2
CTRLC1:
cmp.l #$28000,SD_SCRB(a1)
bne.s CTRLC3
ori.b #1<<MC..SCRN,d0
CTRLC2:
cmp.b SV_MCSTA(a6),d0
beq.s CTRLC3
bsr FLIPIT ; switch screen if necessary
CTRLC3:
MOVE.L A2,SV_KEYQ(A6) ; set current keyboard queue
CLR.W $AA(A6) ; flashing cursor status
; (word)
MOVEQ #6,D6
bra POLL_EXIt
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SD_CURE:
movem.l d0-d1/d3/a0-a2,-(a7)
move.l a1,a0
jsr $1B86
movem.l (a7)+,d0-d1/d3/a0-a2
rts
movem.l d0-d1/d3/a1-a2,-(a7)
moveq #-1,d3
moveq #SD.CURE,d0
trap #3
movem.l (a7)+,d0-d1/d3/a1-a2
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Entry: A2 = pointer to keyboard queue
; Exit: A0 = Channel ID
; A1 = Channel base
FNDCHN:
movem.l d0-d1/a3-a4,-(a7)
move.l SV_CHBAS(a6),a0
move.l SV_CHTOP(a6),a4
moveq #0,d0
FNDLUP:
move.l (a0),a1 ; channel vars?
cmpa.l a1,a2
blt.s FNDCNT
move.l (a1),d1
lea 0(a1,d1.w),a3
cmpa.l a3,a2
blt.s FNDDUN
FNDCNT:
addq.w #1,d0
addq.l #4,a0
cmp.l a0,a4
bgt.s FNDLUP
suba.l a1,a1
moveq #0,d0
bra.s FNDXIT ; not found!
FNDDUN:
swap d0
move.w CH_TAG(a1),d0
swap d0
FNDXIT:
move.l d0,a0 ; channel ID
movem.l (a7)+,d0-d1/a3-a4
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Custom LVL7 routine to initialise hardware
MY_LVL7:
bsr INIT_HW
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.KEYV,a3
move.l KV.LVL7link(a3),a3
move.l 4(a3),4(a7) ; address of next routine
movem.l (a7)+,a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; A patch to replace TRAP#1 calls to: MT_IPCOM (d0=$11)
; and to add the new routine MT_ASC (d0=$27)
MY_TRP1:
bsr INI_A5A6
cmp.b #$11,d0
beq MT_IPCOM
cmp.b #$27,d0
beq MT_ASC
MY_TRP1X:
movem.l (a7)+,d7/a5/a6 ; restore registers
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.KEYV,a3
move.l KV.TRP1link(a3),a3
move.l 4(a3),4(a7) ; address of next routine
movem.l (a7)+,a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; initialise A5 and A6 prior to performing a TRAP routine
INI_A5A6
SUBQ.L #8,A7
MOVE.L 8(A7),-(A7)
MOVEM.L D7/A5/A6,4(A7)
move.l a7,d7
andi.l #$FFFF8000,d7
move.l d7,a6 ; Calc address of sys vars
LEA 4(A7),A5 ; A5 points to saved
; Registers D7,A5,A6
MOVEQ #$7F,D7
AND.L D7,D0
RTS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; TRAP #1 with D0=$11
MT_IPCOM:
cmp.b #9,(a3) ; is IPC command keyrow ?
bne MY_TRP1X
MOVEM.L D4/D6-D7/A0-A1/A3,-(A7)
MOVE.B 6(A3),D7 ; get row number
AND.W #$7,D7 ; only 0..7 are valid
BSR KEYROW
CMP.B #1,D7 ; row 1 ? (contains arrows,
; space and enter)
bne IPCOM_EX
TST.B D1 ; any key pressed ?
beq IPCOM_MO ; no
move.b d1,d0
andi.b #$96,d0
beq IPCOM_EX
movem.l d1-d6/a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
move.w KV.PTRX(a3),d1
move.w KV.PTRY(a3),d2
move.w KV.PTROLDX(a3),d5
move.w KV.PTROLDY(a3),d6
btst.b #4,d0
beq.s IPCOM_1
add.w KV.PTRINCX(a3),d1
add.w KV.PTRINCX(a3),d5
IPCOM_1:
btst.b #1,d0
beq.s IPCOM_2
sub.w KV.PTRINCX(a3),d1
sub.w KV.PTRINCX(a3),d5
IPCOM_2:
btst.b #7,d0
beq.s IPCOM_3
add.w KV.PTRINCY(a3),d2
add.w KV.PTRINCY(a3),d6
IPCOM_3:
btst.b #2,d0
beq.s IPCOM_4
sub.w KV.PTRINCY(a3),d2
sub.w KV.PTRINCY(a3),d6
IPCOM_4:
bsr PTR_CLPX
bsr PTR_CLPY
move.w d1,KV.PTRX(a3)
move.w d2,KV.PTRY(a3)
bsr PTR_POS
move.w d5,d1
move.w d6,d2
bsr PTR_CLPX
bsr PTR_CLPY
move.w d1,KV.PTROLDX(a3)
move.w d2,KV.PTROLDY(a3)
movem.l (a7)+,d1-d6/a3
bra.s IPCOM_EX
IPCOM_MO:
BSR MOUSE
IPCOM_EX:
MOVEM.L (A7)+,D4/D6-D7/A0-A1/A3
moveq #0,d0
bra TRAP1_X
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; KEYROW emulation (row number in D7, -> Columns in D1)
KEYROW:
MOVEM.L A0,-(A7)
move.l AV.KEYV,a0 ; address of keyboard vars
lea KV.STORAwkey(a0),a0
AND.W #$0F,D7
MOVE.B 0(A0,D7.W),D1
MOVEM.L (A7)+,A0
RTS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; read mouse port and generate corresponding keydepression -> D1
MOUSE:
MOVEM.L D0/D2-D5/A0,-(A7)
move.l AV.KEYV,a0 ; address of keyboard vars
clr.b d1 ; preset 'no key'
; --------------------------------------------------------------
moveq #0,d5
move.w KV.PTRINCX(a0),d5
move.w KV.PTRX(a0),d0
sub.w KV.PTRMINX(a0),d0
add.w KV.PTRERRX(a0),d0
ext.l d0
bmi.s MOUS1
divu d5,d0
bra.s MOUS2
MOUS1:
neg.w d0
divu d5,d0
addq.w #1,d0
neg.w d0
MOUS2:
move.w KV.PTROLDX(a0),d4
sub.w KV.PTRMINX(a0),d4
ext.l d4
divu d5,d4
cmp.w d4,d0 ; more or less ?
bmi.s MOUS3
beq.s MOUS4
ori.b #$10,d1 ; right
addq.w #1,d4
bra.s MOUS4
MOUS3:
ori.b #$02,d1 ; left
subq.w #1,d4
MOUS4:
mulu d5,d4
add.w KV.PTRMINX(a0),d4
move.w d4,KV.PTROLDX(a0)
; --------------------------------------------------------------
moveq #0,d6
move.w KV.PTRINCY(a0),d6
move.w KV.PTRY(a0),d0
sub.w KV.PTRMINY(a0),d0
add.w KV.PTRERRY(a0),d0
ext.l d0
bmi.s MOUS5
divu d6,d0
bra.s MOUS6
MOUS5:
neg.w d0
divu d6,d0
addq.w #1,d0
neg.w d0
MOUS6:
move.w KV.PTROLDY(a0),d4
sub.w KV.PTRMINY(a0),d4
ext.l d4
divu d6,d4
cmp.w d4,d0 ; more or less ?
bmi.s MOUS7
beq.s MOUS8
ori.b #$80,d1 ; down
addq.w #1,d4
bra.s MOUS8
MOUS7:
ori.b #$04,d1 ; up
subq.w #1,d4
MOUS8:
mulu d6,d4
add.w KV.PTRMINY(a0),d4
move.w d4,KV.PTROLDY(a0)
; --------------------------------------------------------------
movem.l d1/d3-d4,-(a7)
move.w KV.PTROLDX(a0),d1
move.w KV.PTROLDY(a0),d2
move.w #0,d3
move.w #0,d4
bsr PTR_CLPX
bsr PTR_CLPY
sub.w KV.PTRMINX(a0),d1
ext.l d1
divu d5,d1
mulu d5,d1
add.w KV.PTRMINX(a0),d1
sub.w KV.PTRMINY(a0),d2
ext.l d2
divu d6,d2
mulu d6,d2
add.w KV.PTRMINY(a0),d2
move.w KV.PTROLDX(a0),d3
move.w KV.PTROLDY(a0),d4
sub.w d1,d3
sub.w d2,d4
move.w d1,KV.PTROLDX(a0)
move.w d2,KV.PTROLDY(a0)
sub.w d3,KV.PTRERRX(a0)
sub.w d4,KV.PTRERRY(a0)
movem.l (a7)+,d1/d3-d4
; --------------------------------------------------------------
BTST #6,CIAA_PRA ; left mouse button
BNE.S MOUS9
BSET #6,D1 ; set space
MOUS9:
MOVE.W POTGOR,D0
AND.W #$0400,D0 ; right mouse button
BNE.S MOUS10
BSET #0,D1 ; set enter
MOUS10:
MOVEM.L (A7)+,D0/D2-D5/A0
RTS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Here we start with the rawkey conversion table
; which is used for the KEYROW function.
; The organization is Rownumber,Bitnumber in order
; of the Amiga rawkeys
QLRAWKEY:
DC.B $27,$43,$61,$41,$06,$02,$62,$07
DC.B $60,$50,$65,$55,$35,$15,$FF,$65
DC.B $63,$51,$64,$54,$66,$21,$67,$52
DC.B $57,$45,$30,$20,$FF,$43,$61,$41
DC.B $44,$33,$46,$34,$36,$42,$47,$32
DC.B $40,$37,$27,$10,$FF,$06,$02,$62
DC.B $22,$56,$73,$23,$74,$24,$76,$26
DC.B $76,$22,$75,$FF,$FF,$07,$60,$50
DC.B $16,$11,$53,$10,$10,$13,$11,$FF
DC.B $FF,$FF,$55,$FF,$12,$17,$14,$11
DC.B $01,$03,$04,$00,$05,$01,$03,$04
DC.B $FF,$05,$30,$20,$75,$60,$35,$01
DC.B $70,$70,$31,$71,$72,$72,$71,$71
DC.B $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DC.B $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
DC.B $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
QLRAWEND:
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; TRAP #1 with D0=$27 (New to QDOS 3.10 on Amiga)
; D1=address of new QLASCII table
; this is the recommended way to implement foreign
; Language keybords tables!
MT_ASC:
movem.l a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
move.l d1,KV.QLASCtbl(a3)
movem.l (a7)+,a3
moveq #0,d0
; --------------------------------------------------------------
; exit from TRAP call
TRAP1_X movem.l (a7)+,d7/a5/a6 ; exit from exception
rte
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; conversion table for translating rawkeycode to ASCII code (QL)
; 1) subtract raw key code from 255 (255-(CIAA_SP))
; 2) Shift right the result by 1
; 3) take QLASCII for no shift mode, QLASC_SH for <Shift>,
; QLASC_CT for <Ctrl>, QLASC_SC for <Shift>+<Ctrl>
; 4) read related ASCII code (QL) from table at this offset
QLASCII:
DC.B '`','1','2','3','4','5','6','7','8','9','0',156,39,'\',0,'0'
DC.B 'q','w','e','r','t','z','u','i','o','p',135,'+',0,'1','2','3'
DC.B 'a','s','d','f','g','h','j','k','l',132,128,'#',0,'4','5','6'
DC.B '<','y','x','c','v','b','n','m',44,'.','-',0,0,'7','8','9'
DC.B ' ',194,9,10,10,27,202,0,0,0,'-',0,208,216,200,192
DC.B 232,236,240,244,248,234,238,242,246,250,91,93,'/','*','+',0
QLASC_SH:
DC.B '~','!','"',182,'$','%','&','/','(',')','=','?','^','|',0,'0'
DC.B 'Q','W','E','R','T','Z','U','I','O','P',167,'*',0,'1','2','3'
DC.B 'A','S','D','F','G','H','J','K','L',164,160,'^',0,'4','5','6'
DC.B '>','Y','X','C','V','B','N','M',';',':','_',0,0,'7','8','9'
DC.B 252,194,253,254,254,127,202,0,0,0,'-',0,212,220,204,196
DC.B 234,238,242,246,250,232,236,240,244,248,'{','}','/','*','+',0
QLASC_CT:
DC.B 0,145,146,147,148,149,150,151,152,153,144,0,0,188,0,'0'
DC.B 17,23,5,18,20,26,21,9,15,16,0,0,0,'1','2','3'
DC.B 1,19,4,6,7,8,10,11,12,0,0,0,0,'4','5','6'
DC.B 0,25,24,3,22,2,14,13,140,142,141,0,0,'7','8','9'
DC.B ' ',194,9,10,10,128,202,0,0,0,'-',0,210,218,202,194
DC.B 233,237,241,245,249,235,239,243,247,251,91,93,'/','*','+',0
QLASC_SC:
DC.B '`',129,160,131,132,133,0,0,138,136,137,0,0,28,0,'0'
DC.B 177,183,165,178,180,186,181,169,175,176,0,0,0,'1','2','3'
DC.B 161,179,164,166,167,168,170,171,172,0,0,0,0,'4','5','6'
DC.B 0,185,184,163,182,162,174,173,156,158,0,0,0,'7','8','9'
DC.B ' ',194,9,10,10,27,202,0,0,0,'-',0,214,222,206,198
DC.B 235,239,243,247,251,233,237,241,245,249,91,93,'/','*','+',0
QLASCEND:
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; BASIC extensions specific to AMIGA QDOS
PROC_DEF:
dc.w 5
dc.w B_KEYDT-*
dc.b 5,'KEYDT'
dc.w B_PTR_POS-*
dc.b 7,'PTR_POS'
dc.w B_PTR_INC-*
dc.b 7,'PTR_INC'
dc.w B_PTR_LIMITS-*
dc.b 10,'PTR_LIMITS',0
dc.w 0
dc.w 2
dc.w B_PTR_X-*
dc.b 6,'PTR_X%',0
dc.w B_PTR_Y-*
dc.b 6,'PTR_Y%',0
dc.w 0
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; BASIC proc to link in German keymap again, should it become
; dislocated for some reason.
B_KEYDT:
lea QLASCII(pc),a0 ; address of keyboard table
move.l a0,d1 ; in d1
moveq #$27,d0 ; MT_ASC (Amiga-QDOS 3.10
trap #1 ; and later, only)
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
B_PTR_LIMITS:
moveq #0,d2
moveq #0,d3
move.w #255,d4
move.w #255,d5
cmp.l a3,a5
beq.s PTR_LIMITS
bsr FETCH_W
bne B_PTRLIMX
cmp.w #0,d1
blt RPRT_BP
move.w d1,d2 ; min X
bsr FETCH_W
bne B_PTRLIMX
cmp.w #0,d1
blt RPRT_BP
move.w d1,d3 ; min Y
bsr FETCH_W
bne B_PTRLIMX
cmp.w #255,d1
bgt RPRT_BP
move.w d1,d4 ; max X
bsr FETCH_W
bne B_PTRLIMX
cmp.w #255,d1
bgt RPRT_BP
move.w d1,d5 ; max Y
cmp.l a3,a5
bne RPRT_BP
PTR_LIMITS:
cmp.w d2,d4
ble RPRT_BP
cmp.w d3,d5
ble RPRT_BP
move.l AV.KEYV,a3 ; address of keyboard vars
move.w d2,KV.PTRMINX(a3)
move.w d3,KV.PTRMINY(a3)
move.w d4,KV.PTRMAXX(a3)
move.w d5,KV.PTRMAXY(a3)
sub.w d2,d4
addq.w #1,d4
lsr.w #1,d4
move.w KV.PTRINCX(a3),d0
cmp.w d4,d0
ble.s B_PTRLIM1
move.w d4,KV.PTRINCX(a3)
B_PTRLIM1:
sub.w d3,d5
addq.w #1,d5
lsr.w #1,d5
move.w KV.PTRINCY(a3),d0
cmp.w d5,d0
ble.s B_PTRLIM2
move.w d4,KV.PTRINCY(a3)
B_PTRLIM2:
move.w KV.PTRX(a3),d1
move.w KV.PTRY(a3),d2
bsr PTR_CLPX
bsr PTR_CLPY
move.w d1,KV.PTRX(a3)
move.w d2,KV.PTRY(a3)
bsr PTR_POS
move.w d1,KV.PTROLDX(a3)
move.w d2,KV.PTROLDY(a3)
move.w #0,KV.PTRERRX(a3)
move.w #0,KV.PTRERRY(a3)
moveq #0,d0
B_PTRLIMX:
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
B_PTR_POS:
moveq #0,d1
moveq #0,d2
cmp.l a3,a5
beq.s B_PTR_POS1
bsr FETCH_W
bne.s B_PTR_POSX
move.w d1,d2
bsr FETCH_W
bne.s B_PTR_POSX
cmp.l a3,a5
bne RPRT_BP
exg d1,d2
B_PTR_POS1:
move.l AV.KEYV,a3 ; address of keyboard vars
bsr PTR_CLPX
bsr PTR_CLPY
move.w d1,KV.PTRX(a3)
move.w d2,KV.PTRY(a3)
bsr PTR_POS
move.w d1,KV.PTROLDX(a3)
move.w d2,KV.PTROLDY(a3)
move.w #0,KV.PTRERRX(a3)
move.w #0,KV.PTRERRY(a3)
moveq #0,d0
B_PTR_POSX:
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
B_PTR_INC:
moveq #4,d1
moveq #8,d2
cmp.l a3,a5
beq.s B_PTR_INC1
bsr FETCH_W
bne.s B_PTR_INCX
move.w d1,d2
bsr FETCH_W
bne.s B_PTR_INCX
cmp.l a3,a5
bne RPRT_BP
exg d1,d2
B_PTR_INC1:
bsr PTR_INC
moveq #0,d0
B_PTR_INCX:
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
B_PTR_X:
cmp.l a3,a5
bne RPRT_BP
move.l AV.KEYV,a3 ; address of keyboard vars
move.w KV.PTRX(a3),d1
bra RET_W
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
B_PTR_Y:
cmp.l a3,a5
bne RPRT_BP
move.l AV.KEYV,a3 ; address of keyboard vars
move.w KV.PTRY(a3),d1
bra RET_W
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTR_POS:
movem.l d1-d3,-(a7)
add.w #$2C,d2 ; Y offset $2C
andi.w #$1FF,d2 ; Y within range
move.w d2,d3
lsl.l #8,d3
lsl.l #1,d3
addi.w #$A0,d1 ; X offset $A0
andi.w #$1FF,d1 ; X within range
or.w d1,d3
ror.l #1,d3
swap d3
addi.w #$10,d2 ; Height $10
lsl.w #8,d2
roxl.w #1,d3
roxl.w #1,d3
or.w d2,d3
move.l d3,SPRLST
movem.l (a7)+,d1-d3
PTR_POSX:
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTR_CLPX:
movem.l d5/a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
move.w KV.PTRMINX(a3),d5
cmp.w d5,d1
blt.s PTR_CLP1
move.w KV.PTRMAXX(a3),d5
cmp.w d5,d1
bgt.s PTR_CLP1
moveq #0,d3
bra.s PTR_CLP2
PTR_CLP1:
add.w d1,d3
sub.w d5,d3
move.w d5,d1
PTR_CLP2:
movem.l (a7)+,d5/a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTR_CLPY:
movem.l d5/a3,-(a7)
move.l AV.KEYV,a3 ; address of keyboard vars
move.w KV.PTRMINY(a3),d5
cmp.w d5,d2
blt.s PTR_CLP3
move.w KV.PTRMAXY(a3),d5
cmp.w d5,d2
bgt.s PTR_CLP3
moveq #0,d4
bra.s PTR_CLP4
PTR_CLP3:
add.w d2,d4
sub.w d5,d4
move.w d5,d2
PTR_CLP4:
movem.l (a7)+,d5/a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTR_INC:
move.l AV.KEYV,a3 ; address of keyboard vars
tst.w d1
beq.s PTR_INCX
move.w KV.PTRMAXX(a3),d0
sub.w KV.PTRMINX(a3),d0
addq.w #1,d0
lsr.w #1,d0
cmp.w d0,d1
bgt.s PTR_INCX
PTR_INC1:
tst.w d2
beq.s PTR_INCX
move.w KV.PTRMAXY(a3),d0
sub.w KV.PTRMINY(a3),d0
addq.w #1,d0
lsr.w #1,d0
cmp.w d0,d2
bgt.s PTR_INCX
move.w d1,KV.PTRINCX(a3)
move.w d2,KV.PTRINCY(a3)
PTR_INCX:
moveq #0,d0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Fetch one Word
FETCH_W:
movem.l a2,-(a7)
move.w CA.GTINT,a2
bsr.s GET_ONE
bne.s FETCH_WX
move.l a1,BV_RIP(a6)
moveq #0,d1
move.w 0(a6,a1.l),d1
addq.l #2,BV_RIP(a6)
FETCH_WX:
movem.l (a7)+,a2
tst.l d0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; This routine gets one parameter and returns it on the maths
; stack, pointed to by (A1).
;
; Entry: A2.L routine to call (i.e. CA.GTINT)
; A3.L pointer to first parameter
; A5.L pointer to last parameter
;
; Exit: A3.L updated
; A5.L updated
; A1.L updated pointer to top of maths stack
; D0.L error code
GET_ONE:
movem.l d1-d6/a0/a2,-(a7)
lea 8(a3),a0
cmp.l a0,a5
blt.s GET_ONEBp
move.l BV_RIP(a6),a1
move.l a5,-(a7)
move.l a0,a5
move.l a5,-(a7)
jsr (a2)
movem.l (a7)+,a0/a5
tst.l d0
bne.s GET_ONEX
move.l a0,a3
move.l a1,BV_RIP(a6)
bra.s GET_ONEX
GET_ONEBp:
moveq #ERR.BP,d0
GET_ONEX:
movem.l (a7)+,d1-d6/a0/a2
tst.l d0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Return word d1.w to BASIC
RET_W:
move.l d1,d4
moveq.l #2,d1
move.w BV.CHRIX,a2
jsr (a2)
move.l d4,d1
move.l BV_RIP(a6),a1 ; Get arith stack pointer
subq.l #2,a1 ; room for 2 bytes
move.l a1,BV_RIP(a6)
move.w d1,0(a6,a1.l) ; Put int number on stack
moveq.l #3,d4 ; set Integer type
moveq.l #ERR.OK,d0 ; no errors
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RPRT_BP:
moveq #ERR.BP,d0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
END